package com.tensai.study.java.basic.asynchronous.thread.executor.task;

import cn.hutool.core.thread.NamedThreadFactory;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;

import java.util.concurrent.*;

/**
 * <li>{@link Callable} 规定的方法是 {@link Callable#call()},{@link Runnable} 规定的方法是 {@link Runnable#run()}.</li>
 * <li>{@link Callable} 的任务执行后可返回值，而 {@link Runnable} 的任务是不能返回值得</li>
 * <li>{@link Callable#call()} 方法可以抛出异常，{@link Runnable#run()}方法不可以</li>
 * <li>运行{@link Callable}任务可以拿到一个{@link Future}对象，表示异步计算的结果。
 * 它提供了检查计算是否完成的方法，以等待计算的完成，并检索计算的结果。
 * 通过{@link Future}对象可以了解任务执行情况，可取消任务的执行，还可获取执行结果。</li>
 *
 * @author Tensai
 * @since java-1.5
 */
@Slf4j
public class CallableTest implements Callable<String> {


	/**
	 * Computes a result, or throws an exception if unable to do so.
	 *
	 * @return computed result
	 * @throws Exception if unable to compute a result
	 */
	@Override
	public String call() throws Exception {
		try {
			Thread.sleep(5000);
			log.info("Thread-Name -> {}", Thread.currentThread().getName());
			return "return String";
		} catch (Exception e) {
			e.printStackTrace();
			return "exception";
		}
	}

	@Test
	public void test() throws ExecutionException, InterruptedException {
		Callable<String> callable = new CallableTest();
		FutureTask<String> task = new FutureTask<>(callable);
		long beginTime = System.currentTimeMillis();
		//创建线程
		new ThreadPoolExecutor(10, 10, 60, TimeUnit.MINUTES,
				new ArrayBlockingQueue<>(20), new NamedThreadFactory(getClass().getName(), true)
		).execute(task);
		//调用get()方法阻塞主线程
		String str = task.get();
		long endTime = System.currentTimeMillis();
		System.out.println("hello :" + str);
		System.out.println("time :" + (endTime - beginTime) / 1000);
	}
}
